package hu.mapro.rollerx.core;

import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;

public class Ground1 extends AbstractGround {

	private static final float GROUND_WIDTH = 150;
	private static final float GROUND_AMPLITUDE = 25;
	
	private static final int GROUND_FRACTAL_LEVELS = 6;
	private static final float GROUND_FRACTAL_DENOMINATOR = 2.0f;
	
	
	float[] terrainVertices;
	int terrainVerticeIdx = 0;
	
	void generateFractal(float carWidth) {
		float platformWidth = getPlatformWidth(carWidth);
		
		createVertexArray(
				(1 << GROUND_FRACTAL_LEVELS) + 1 + 2
		);

		addVertex(-platformWidth, 0);
		
		float y1 = 0;
		float y2 = MathUtils.random(-GROUND_AMPLITUDE, GROUND_AMPLITUDE);
		
		fractal(
				0f,
				y1,
				GROUND_WIDTH,
				y2,
				GROUND_AMPLITUDE,
				GROUND_FRACTAL_LEVELS
		);
		
		addVertex(GROUND_WIDTH, y2);
		addVertex(GROUND_WIDTH+platformWidth, y2);
	}
	
	void createVertexArray(int size) {
		terrainVertices = new float[size*2];
	}
	
	void addVertex(float x, float y) {
		terrainVertices[terrainVerticeIdx++] = x;
		terrainVertices[terrainVerticeIdx++] = y;
	}

	void fractal(
			float x1,
			float y1,
			float x2, 
			float y2, 
			float d,
			int n
	) {
		if (n==0) {
			addVertex(x1, y1);
		} else {
			float xm = (x1+x2)/2;
			float ym = (float) ((y1+y2)/2 + (Math.random()*d*2)-d);
			fractal(x1, y1, xm, ym, d/GROUND_FRACTAL_DENOMINATOR, n-1);
			fractal(xm, ym, x2, y2, d/GROUND_FRACTAL_DENOMINATOR, n-1);
		}
	}

	static float getPlatformWidth(float carWidth) {
		return carWidth*2;
	}
	
	@Override
	public Vector2 getCarPosition(float carWidth, float carHeight) {
		return new Vector2(-getPlatformWidth(carWidth)/2,0);
	}

	@Override
	Vector2[][] generateVertices(float carWidth, float carHeight) {
		generateFractal(carWidth);
		Vector2[] vecs = new Vector2[terrainVertices.length];
		for (int i=0;i<vecs.length/2;i++) {
			vecs[i] = new Vector2(terrainVertices[i*2], terrainVertices[i*2+1]);
			vecs[vecs.length-i-1] = new Vector2(terrainVertices[i*2], terrainVertices[i*2+1]+carHeight*3);
		}
		return new Vector2[][] {vecs};
	}

	
	
}
